﻿using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;

namespace Interactive.Utility.Extension {
    public static class StringExt {
        /// <summary>
        /// 判断输入字符串是否为空,简单偷懒封装
        /// </summary>
        /// <param name="strInput"></param>
        /// <returns></returns>
        public static bool IsEmptyOrNull(this string strInput){
            return string.IsNullOrEmpty(strInput);
        }

        /// <summary>
        /// 检测是否符合email格式
        /// </summary>
        /// <param name="strEmail">要判断的email字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsValidEmail(this string strEmail){
            return Regex.IsMatch(strEmail,
                                 @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        public static bool IsValidDoEmail(this string strEmail){
            return Regex.IsMatch(strEmail,
                                 @"^@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
        }

        /// <summary>
        /// 检测是否是正确的Url
        /// </summary>
        /// <param name="strUrl">要验证的Url</param>
        /// <returns>判断结果</returns>
        public static bool IsUrl(this string strUrl){
            return Regex.IsMatch(strUrl,
                                 @"^(http|https)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{1,10}))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&%\$#\=~_\-]+))*$");
        }


        /// <summary>
        /// 判断是否为base64字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsBase64String(this string str){
            //A-Z, a-z, 0-9, +, /, =
            return Regex.IsMatch(str, @"[A-Za-z0-9\+\/\=]");
        }

        /// <summary>
        /// 检测是否有Sql危险字符
        /// </summary>
        /// <param name="str">要判断字符串</param>
        /// <returns>判断结果</returns>
        public static bool IsSafeSqlString(this string str){
            return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }


        /// <summary>
        /// 是否是时间格式,注意这里说的是时间格式,没有日期成分
        /// </summary>
        /// <returns></returns>
        public static bool IsTime(this string timeval){
            return Regex.IsMatch(timeval, @"^((([0-1]?[0-9])|(2[0-3])):([0-5]?[0-9])(:[0-5]?[0-9])?)$");
        }


        /// <summary>
        /// 是否为ip,完全匹配,不能包含如192.168.1.*
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIp(this string ip){
            return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
        }

        /// <summary>
        /// 可以包含段,如192.168.*.*
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        public static bool IsIpSect(this string ip){
            return Regex.IsMatch(ip,
                                 @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){2}((2[0-4]\d|25[0-5]|[01]?\d\d?|\*)\.)(2[0-4]\d|25[0-5]|[01]?\d\d?|\*)$");
        }


        /// <summary>
        /// 返回指定IP是否在指定的IP数组所限定的范围内, IP数组内的IP地址可以使用*表示该IP段任意, 例如192.168.1.*
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="iparray"></param>
        /// <returns></returns>
        public static bool InIPArray(this string ip, string[] iparray){
            string[] userip = ip.SplitString(@".");
            for (int ipIndex = 0; ipIndex < iparray.Length; ipIndex++){
                string[] tmpip = iparray[ipIndex].SplitString(@".");
                int r = 0;
                for (int i = 0; i < tmpip.Length; i++){
                    if (tmpip[i] == "*")
                        return true;

                    if (userip.Length > i){
                        if (tmpip[i] == userip[i])
                            r++;
                        else
                            break;
                    }
                    else
                        break;
                }
                if (r == 4)
                    return true;
            }
            return false;
        }


        /// <summary>
        /// MD5函数
        /// </summary>
        /// <param name="str">原始字符串</param>
        /// <returns>MD5结果</returns>
        public static string MD5(this string str){
            byte[] b = Encoding.Default.GetBytes(str);
            b = new MD5CryptoServiceProvider().ComputeHash(b);
            string ret = "";
            for (int i = 0; i < b.Length; i++)
                ret += b[i].ToString("x").PadLeft(2, '0');
            return ret;
        }

        /// <summary>
        /// SHA256函数
        /// </summary>
        /// /// <param name="str">原始字符串</param>
        /// <returns>SHA256结果</returns>
        public static string SHA256(this string str){
            byte[] SHA256Data = Encoding.UTF8.GetBytes(str);
            var Sha256 = new SHA256Managed();
            byte[] Result = Sha256.ComputeHash(SHA256Data);
            return Convert.ToBase64String(Result); //返回长度为44字节的字符串
        }


        /// <summary>
        /// 改正sql语句中的转义字符
        /// </summary>
        public static string MashSql(this string str){
            string str2;

            if (str == null)
                str2 = "";
            else{
                str = str.Replace("\'", "'");
                str2 = str;
            }
            return str2;
        }

        /// <summary>
        /// 替换sql语句中的有问题符号
        /// </summary>
        public static string ChkSql(this string str){
            string str2;

            if (str == null)
                str2 = "";
            else{
                str = str.Replace("'", "''");
                str2 = str;
            }
            return str2;
        }


        /// <summary>
        /// 分割字符串,如果没有strSplit,则返回整个字符串
        /// </summary>
        public static string[] SplitString(this string strContent, string strSplit){
            if (!string.IsNullOrEmpty(strContent)){
                if (strContent.IndexOf(strSplit) < 0){
                    string[] tmp = {strContent};
                    return tmp;
                }
                return strContent.Split(new[]{strSplit}, StringSplitOptions.None);
            }
            return new string[]{};
        }

        /// <summary>
        /// 分割字符串,返回指定count唯的数组
        /// </summary>
        /// <returns></returns>
        public static string[] SplitString(string strContent, string strSplit, int count){
            var result = new string[count];

            string[] splited = SplitString(strContent, strSplit);

            for (int i = 0; i < count; i++)
                result[i] = i < splited.Length ? splited[i] : string.Empty;

            return result;
        }

        /// <summary>
        /// 过滤字符串数组中每个元素为合适的大小
        /// 当长度小于minLength时，忽略掉,-1为不限制最小长度
        /// 当长度大于maxLength时，取其前maxLength位
        /// 如果数组中有null元素，会被忽略掉
        /// </summary>
        /// <param name="strArray"></param>
        /// <param name="minLength">单个元素最小长度</param>
        /// <param name="maxLength">单个元素最大长度</param>
        /// <returns></returns>
        public static string[] PadStringArray(this string[] strArray, int minLength, int maxLength){
            if (minLength > maxLength){
                int t = maxLength;
                maxLength = minLength;
                minLength = t;
            }

            for (int i = 0; i < strArray.Length; i++){
                if (string.IsNullOrEmpty(strArray[i]))
                    continue;
                if (minLength > -1 && strArray[i].Length < minLength){
                    strArray[i] = null;
                    continue;
                }
                if (strArray[i].Length > maxLength)
                    strArray[i] = strArray[i].Substring(0, maxLength);
            }

            return (from str in
                        strArray
                    where str != null
                    select str).ToArray();
        }

        /// <summary>
        /// 分割字符串
        /// </summary>
        /// <param name="strContent">被分割的字符串</param>
        /// <param name="strSplit">分割符</param>
        /// <param name="ignoreRepeatItem">忽略重复项</param>
        /// <param name="maxElementLength">单个元素最大长度</param>
        /// <returns></returns>
        public static string[] SplitString(this string strContent, string strSplit, bool ignoreRepeatItem,
                                           int maxElementLength){
            string[] result = SplitString(strContent, strSplit);

            return ignoreRepeatItem ? DistinctStringArray(result, maxElementLength) : result;
        }

        public static string[] SplitString(this string strContent, string strSplit, bool ignoreRepeatItem,
                                           int minElementLength, int maxElementLength){
            string[] result = SplitString(strContent, strSplit);

            if (ignoreRepeatItem)
                result = DistinctStringArray(result);
            return PadStringArray(result, minElementLength, maxElementLength);
        }

        /// <summary>
        /// 分割字符串
        /// </summary>
        /// <param name="strContent">被分割的字符串</param>
        /// <param name="strSplit">分割符</param>
        /// <param name="ignoreRepeatItem">忽略重复项</param>
        /// <returns></returns>
        public static string[] SplitString(string strContent, string strSplit, bool ignoreRepeatItem){
            return SplitString(strContent, strSplit, ignoreRepeatItem, 0);
        }


        /// <summary>
        /// 进行指定的替换(脏字过滤)
        /// </summary>
        public static string StrFilter(this string str, string bantext){
            string text1;
            string text2;
            string[] textArray1 = bantext.SplitString("\r\n");
            for (int num1 = 0; num1 < textArray1.Length; num1++){
                text1 = textArray1[num1].Substring(0, textArray1[num1].IndexOf("="));
                text2 = textArray1[num1].Substring(textArray1[num1].IndexOf("=") + 1);
                str = str.Replace(text1, text2);
            }
            return str;
        }


  


        /// <summary>
        /// 替换html字符
        /// </summary>
        public static string EncodeHtml(this string strHtml){
            if (strHtml != ""){
                strHtml = strHtml.Replace(",", "&def");
                strHtml = strHtml.Replace("'", "&dot");
                strHtml = strHtml.Replace(";", "&dec");
                return strHtml;
            }
            return "";
        }


        /// <summary>
        /// 为脚本替换特殊字符串
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReplaceStrToScript(this string str){
            str = str.Replace("\\", "\\\\");
            str = str.Replace("'", "\\'");
            str = str.Replace("\"", "\\\"");
            return str;
        }


        /// <summary>
        /// 将全角数字或符合转换为正常数字和符合
        /// </summary>
        /// <param name="sbcCase"></param>
        /// <returns></returns>
        public static string SbcCaseToNumberic(this string sbcCase){
            char[] c = sbcCase.ToCharArray();
            for (int i = 0; i < c.Length; i++){
                byte[] b = Encoding.Unicode.GetBytes(c, i, 1);
                if (b.Length == 2){
                    if (b[1] == 255){
                        b[0] = (byte) (b[0] + 32);
                        b[1] = 0;
                        c[i] = Encoding.Unicode.GetChars(b)[0];
                    }
                }
            }
            return new string(c);
        }


        /// <summary>
        /// 从字符串的指定位置截取指定长度的子字符串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="startIndex">子字符串的起始位置</param>
        /// <param name="length">子字符串的长度</param>
        /// <returns>子字符串</returns>
        public static string CutString(this string str, int startIndex, int length){
            if (startIndex >= 0){
                if (length < 0){
                    length = length*-1;
                    if (startIndex - length < 0){
                        length = startIndex;
                        startIndex = 0;
                    }
                    else
                        startIndex = startIndex - length;
                }


                if (startIndex > str.Length)
                    return "";
            }
            else{
                if (length < 0)
                    return "";

                if (length + startIndex > 0){
                    length = length + startIndex;
                    startIndex = 0;
                }
                else
                    return "";
            }

            if (str.Length - startIndex < length)
                length = str.Length - startIndex;

            return str.Substring(startIndex, length);
        }

        /// <summary>
        /// 从字符串的指定位置开始截取到字符串结尾的了符串
        /// </summary>
        /// <param name="str">原字符串</param>
        /// <param name="startIndex">子字符串的起始位置</param>
        /// <returns>子字符串</returns>
        public static string CutString(this string str, int startIndex){
            return CutString(str, startIndex, str.Length);
        }

        /// <summary>
        /// 取指定长度的字符串
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_StartIndex">起始位置</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetSubString(this string p_SrcString, int p_StartIndex, int p_Length, string p_TailString){
            string myResult = p_SrcString;

            #region 下面的是如果是日文或韩文,这这里我把他省略了
            //Byte[] bComments = Encoding.UTF8.GetBytes(p_SrcString);
            //foreach (char c in Encoding.UTF8.GetChars(bComments))
            //{    //当是日文或韩文时(注:中文的范围:\u4e00 - \u9fa5, 日文在\u0800 - \u4e00, 韩文为\xAC00-\xD7A3)
            //    if ((c > '\u0800' && c < '\u4e00') || (c > '\xAC00' && c < '\xD7A3'))
            //    {
            //        //if (System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\u0800-\u4e00]+") || System.Text.RegularExpressions.Regex.IsMatch(p_SrcString, "[\xAC00-\xD7A3]+"))
            //        //当截取的起始位置超出字段串长度时
            //        if (p_StartIndex >= p_SrcString.Length)
            //        {
            //            return "";
            //        }
            //        else
            //        {
            //            return p_SrcString.Substring(p_StartIndex, ((p_Length + p_StartIndex) > p_SrcString.Length) ? (p_SrcString.Length - p_StartIndex) : p_Length);
            //        }
            //    }
            //}
            #endregion

            if (p_Length >= 0){
                byte[] bsSrcString = Encoding.Default.GetBytes(p_SrcString);

                //当字符串长度大于起始位置
                if (bsSrcString.Length > p_StartIndex){
                    int p_EndIndex = bsSrcString.Length;

                    //当要截取的长度在字符串的有效长度范围内
                    if (bsSrcString.Length > (p_StartIndex + p_Length))
                        p_EndIndex = p_Length + p_StartIndex;
                    else{
                        //当不在有效范围内时,只取到字符串的结尾

                        p_Length = bsSrcString.Length - p_StartIndex;
                        p_TailString = "";
                    }


                    int nRealLength = p_Length;
                    var anResultFlag = new int[p_Length];

                    int nFlag = 0;
                    for (int i = p_StartIndex; i < p_EndIndex; i++){
                        if (bsSrcString[i] > 127){
                            nFlag++;
                            if (nFlag == 3) //这里是这个算法的经典之处121212121,为一,代表是基数个,所有最后要加1
                                nFlag = 1;
                        }
                        else
                            nFlag = 0;

                        anResultFlag[i] = nFlag;
                    }

                    if ((bsSrcString[p_EndIndex - 1] > 127) && (anResultFlag[p_Length - 1] == 1))
                        nRealLength = p_Length + 1;

                    var bsResult = new byte[nRealLength];

                    Array.Copy(bsSrcString, p_StartIndex, bsResult, 0, nRealLength);

                    myResult = Encoding.Default.GetString(bsResult);

                    myResult = myResult + p_TailString;
                }
            }

            return myResult;
        }


        /// <summary>
        /// 字符串如果操过指定长度则将超出的部分用指定字符串代替
        /// </summary>
        /// <param name="p_SrcString">要检查的字符串</param>
        /// <param name="p_Length">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetSubString(this string p_SrcString, int p_Length, string p_TailString){
            return GetSubString(p_SrcString, 0, p_Length, p_TailString);
            //return GetSubStrings(p_SrcString, p_Length*2, p_TailString);
        }

        /// <summary>
        /// 字符串如果操过指定长度则将超出的部分用指定字符串代替,简单版本,没有区分文本和数字
        /// </summary>
        /// <param name="srcStirng">源字符</param>
        /// <param name="length">指定长度</param>
        /// <param name="tailString">用于替换的字符串</param>
        /// <returns>满足条件的字符串</returns>
        public static string GetSubEasyString(this string srcStirng, int length, string tailString)
        {
            if (string.IsNullOrEmpty(srcStirng))
                return "";
            var i = srcStirng.Length;
            if (i == length + 1)
                return srcStirng;
            if(i>length){
                
                return srcStirng.Substring(0, length) + tailString;
            }
            return srcStirng;
            

        }

        /// <summary>
        /// 字符串如果操过指定长度则将超出的部分用指定字符串代替
        /// </summary>
        /// <param name="str">要检查的字符串</param>
        /// <param name="len">指定长度</param>
        /// <param name="p_TailString">用于替换的字符串</param>
        /// <returns>截取后的字符串</returns>
        public static string GetUnicodeSubString(this string str, int len, string p_TailString){
            string result = string.Empty; // 最终返回的结果
            int byteLen = Encoding.Default.GetByteCount(str); // 单字节字符长度
            int charLen = str.Length; // 把字符平等对待时的字符串长度
            int byteCount = 0; // 记录读取进度
            int pos = 0; // 记录截取位置
            if (byteLen > len){
                for (int i = 0; i < charLen; i++){
                    if (Convert.ToInt32(str.ToCharArray()[i]) > 255) // 按中文字符计算加2
                        byteCount += 2;
                    else // 按英文字符计算加1
                        byteCount += 1;
                    if (byteCount > len) // 超出时只记下上一个有效位置
                    {
                        pos = i;
                        break;
                    }
                    if (byteCount == len) // 记下当前位置
                    {
                        pos = i + 1;
                        break;
                    }
                }

                if (pos >= 0)
                    result = str.Substring(0, pos) + p_TailString;
            }
            else
                result = str;

            return result;
        }

       


        /// <summary>
        /// 返回文件是否存在
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否存在</returns>
        public static bool FileExists(this string filename){
            return File.Exists(filename);
        }


        /// <summary>
        /// 返回URL中结尾的文件名
        /// </summary>		
        public static string GetUrlFilename(this string url){
            if (url == null)
                return "";
            string[] strs1 = url.Split(new[]{'/'});
            return strs1[strs1.Length - 1].Split(new[]{'?'})[0];
        }

        /// <summary>
        /// 判断文件名是否为浏览器可以直接显示的图片文件名
        /// </summary>
        /// <param name="filename">文件名</param>
        /// <returns>是否可以直接显示</returns>
        public static bool IsImgFilename(this string filename){
            filename = filename.Trim();
            if (filename.EndsWith(".") || filename.IndexOf(".") == -1)
                return false;
            string extname = filename.Substring(filename.LastIndexOf(".") + 1).ToLower();
            return (extname == "jpg" || extname == "jpeg" || extname == "png" || extname == "bmp" || extname == "gif");
        }


        /// <summary>
        /// 返回指定的路径字符串的扩展名
        /// </summary>
        /// <param name="filename">路径字符串</param> 
        public static string GetFileExtension(this string filename){
            if (string.IsNullOrEmpty(filename))
                return string.Empty;
            return Path.GetExtension(filename);
        }

        /// <summary>
        /// 严格过滤
        /// </summary>
        /// <param name="strInput">待过滤的字符串</param>
        /// <returns></returns>
        public static string StrCheckStrict(this string strInput){
            if (strInput.IsEmptyOrNull())
                return "";
            // @"[^\u4E00-\u9FA5a-zA-Z0-9_\.!,~～！，。？：’‘”“、:;.=?'$/@# ￥%……&×（）《》\-<>\(\)\{\}\[\]\^\@０-９Ａ-Ｚ－+＋．＂＂]",
            strInput = Regex.Replace(strInput,
                                     @"[^\u4E00-\u9FA5a-zA-Z0-9_\.!,~～！，。？：’‘”“、:;.=?'$/@# ￥%……×（）《》\-\(\)\{\}\[\]\^\@０-９Ａ-Ｚ－+＋．＂＂]",
                                     "");
            return strInput;
        }

        /// <summary>
        /// 返回不带任何网页标签的文本内容
        /// </summary>
        /// <param name="content">页面内容</param>
        /// <returns></returns>
        public static string GetNoTagFilterContent(this string content)
        {
            string tempStr = content;
            if (!string.IsNullOrEmpty(tempStr)) tempStr = Regex.Replace(tempStr, @"<[\w\W]+?>", "");
            return tempStr;
        }

        /// <summary>
        /// 严格过滤2,博客等文章类专用
        /// </summary>
        /// <param name="checkstr">待过滤的字符串</param>
        /// <returns></returns>
        public static string StrCheckStrick1(this string checkstr)
        {
            if (checkstr.IsEmptyOrNull())
                return string.Empty;
            checkstr = checkstr.Replace("&", "&amp;");
            checkstr = checkstr.Replace("<", "&lt;");
            checkstr = checkstr.Replace(">", "&gt;");
            checkstr = Regex.Replace(checkstr, @"[^\u4E00-\u9FA5a-zA-Z0-9_\.!,，。；“”‘’！?？（）~\(\)\{\}\[\]\^\@]", "");
            return checkstr;

        }


        /// <summary>
        /// 宽松过滤
        /// </summary>
        /// <param name="strInput">待过滤的字符串</param>
        /// <returns></returns>
        public static string StrCheckLoose(this string strInput){
            if (string.IsNullOrEmpty(strInput)) return "";
            strInput = strInput.Replace("&amp;", "&");
            strInput = strInput.Replace("&", "&amp;");
            strInput = strInput.Replace("<", "&lt;");
            strInput = strInput.Replace(">", "&gt;");
            strInput = strInput.Replace("\"", "&quot;");
            strInput = strInput.Replace("'", "&apos;");
            strInput = strInput.Replace("\\$", "");
            strInput = strInput.Replace("[\\x00-\\x1F]", ""); //不可见字符
            return strInput;
        }

        #region string数组

        /// <summary>
        /// 清除字符串数组中的重复项
        /// </summary>
        /// <param name="strArray">字符串数组</param>
        /// <param name="maxElementLength">字符串数组中单个元素的最大长度,为-1或0则不限长度</param>
        /// <returns></returns>
        public static string[] DistinctStringArray(this string[] strArray, int maxElementLength){
            var h = new Hashtable();

            foreach (string s in strArray){
                string k = s;
                if (maxElementLength > 0 && k.Length > maxElementLength)
                    k = k.Substring(0, maxElementLength);
                h[k.Trim()] = s;
            }

            var result = new string[h.Count];

            h.Keys.CopyTo(result, 0);

            return result;
        }

        /// <summary>
        /// 清除字符串数组中的重复项
        /// </summary>
        /// <param name="strArray">字符串数组</param>
        /// <returns></returns>
        public static string[] DistinctStringArray(this string[] strArray){
            return DistinctStringArray(strArray, 0);
        }

        /// <summary>
        /// 判断给定的字符串数组(strNumber)中的数据是不是都为数值型
        /// </summary>
        /// <param name="strNumber">要确认的字符串数组</param>
        /// <returns>是则返加true 不是则返回 false</returns>
        public static bool IsNumericArray(this string[] strNumber){
            if (strNumber == null)
                return false;
            if (strNumber.Length < 1)
                return false;
            foreach (string id in strNumber){
                if (!id.IsNumeric())
                    return false;
            }
            return true;
        }

        #endregion

        #region 特殊方法

        /// <summary>
        /// 合并一组可枚举的对象为字符串
        /// </summary>
        /// <param name="enumerable">被枚举对象</param>
        /// <param name="seperator">分隔符</param>
        /// <returns></returns>
        public static string ConcatEnumerable(this IEnumerable enumerable, string seperator){
            IEnumerator enumerator = enumerable.GetEnumerator();
            if (!enumerator.MoveNext())
                return string.Empty;
            var text = new StringBuilder(128);
            text.Append(enumerator.Current);
            while (enumerator.MoveNext())
                text.Append(seperator + enumerator.Current);
            return text.ToString();
        }

        /// <summary>
        /// 合并一组可枚举的对象为字符串,没有null
        /// </summary>
        /// <param name="enumerable">被枚举对象</param>
        /// <param name="seperator">分隔符</param>
        /// <returns></returns>
        public static string ConcatEnumerableNoNull(this IEnumerable enumerable, string seperator)
        {
            IEnumerator enumerator = enumerable.GetEnumerator();
            if (!enumerator.MoveNext())
                return string.Empty;
            var text = new StringBuilder(128);
            text.Append(enumerator.Current);
            while (enumerator.MoveNext()&&enumerator.Current!=null)
                text.Append(seperator + enumerator.Current);
            return text.ToString();
        }


        #endregion

        #region 网页相关

        /// <summary>
        /// 得到链接,通过增加显示文字
        /// </summary>
        /// <param name="url">链接</param>
        /// <param name="showText">显示文字</param>
        public static string ToLinkByUrl(this string url, string showText){
            return "<a href='" + url + "'>" + showText + "</a>";
        }

        /// <summary>
        /// 得到链接,通过增加一个连接
        /// </summary>
        /// <param name="showText">显示文字</param>
        /// <param name="url">链接</param>
        /// <returns></returns>
        public static string ToLinkByShowText(this string showText, string url){
            return url.ToLinkByUrl(showText);
        }

        /// <summary>
        /// 得到图片,通过图片地址
        /// </summary>
        /// <param name="url">图片地址</param>
        /// <param name="altText">图片alt内容</param>
        /// <returns></returns>
        public static string ToImg(this string url, string altText){
            return "<img src='" + url + "' alt='" + altText + "' />";
        }

        /// <summary>
        /// 得到图片,通过图片地址,alt为默认值loading...
        /// </summary>
        /// <param name="url">图片地址</param>
        /// <returns></returns>
        public static string ToImg(this string url){
            return url.ToImg("loading...");
        }


        /// <summary>
        /// 日期人性化显示
        /// </summary>
        /// <param name="time">要显示的日期</param>
        /// <returns></returns>
        public static string DateDisplay(this DateTime time)
        {
            TimeSpan ts = DateTime.Now - time;
            if ((int)ts.TotalDays >= 3)
            {
                return time.ToString("yyyy-MM-dd HH:mm");
            }
            if ((int)ts.TotalDays >= 1 && (int)ts.TotalDays < 3)
            {
                return (int)ts.TotalDays + "天前";
            }
            if ((int)ts.TotalHours >= 1 && (int)ts.TotalHours < 24)
            {
                return (int)ts.TotalHours + "小时前";
            }
            if ((int)ts.TotalMinutes >= 1 && (int)ts.TotalMinutes < 60)
            {
                return (int)ts.TotalMinutes + "分钟前";
            }
            return (int)ts.TotalSeconds + "秒前";
        }


        #endregion
    }
}